//
//  HMRefreshControl.swift
//  MicroBlog
//
//  Created by Apple on 16/9/25.
//  Copyright © 2016年 Apple. All rights reserved.
//

import UIKit
//下拉刷新控件高度
private let HMRefreshControlHeight: CGFloat = 50
//下拉状态
enum HMRefreshControlState {
    //下拉刷新
    case normal
    //松手刷新
    case pulling
    //正在刷新
    case refreshing
}
class HMRefreshControl: UIControl {
    //记录当前滚动视图
    var currentScrollView: UIScrollView?
    //当前控件的刷新状态
    var HMState: HMRefreshControlState = .normal {
        //根据刷新状态
        didSet {
            switch HMState {
            case .normal:
                print("normal")
                //箭头重置,箭头显示,风火轮停止,更新显示内容
                iconImageView.isHidden = false
                indicatorView.stopAnimating()
                UIView.animate(withDuration: 0.5, animations: {
                    self.iconImageView.transform = .identity
                })
                //初始化成原始位置
                //上次正在刷新
                if oldValue == .refreshing {
                    UIView.animate(withDuration: 0.25, animations: {
                        self.currentScrollView?.contentInset.top -= HMRefreshControlHeight
                    })
                }
                messageLabel.text = "下拉刷新"
            case .pulling:
                print("pulling")
                //箭头调转,更新显示内容
                UIView.animate(withDuration: 0.5, animations: {
                    self.iconImageView.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI))
                })
                messageLabel.text = "松手刷新"
            case .refreshing:
                print("refreshing")
                //隐藏箭头,开启风火轮,更新显示内容
                iconImageView.isHidden = true
                indicatorView.startAnimating()
                messageLabel.text = "正在加载···"
                //设置停留,核心点
                UIView.animate(withDuration: 0.25, animations: {
                    self.currentScrollView?.contentInset.top += HMRefreshControlHeight
                })
                //主动发送事件,刷新数据请求
                //核心点,发送值改变事件
                sendActions(for: .valueChanged)
            }
        }
    }
    //结束刷新
    func endRefreshing() {
        HMState = .normal
    }
    //下拉箭头
    private lazy var iconImageView: UIImageView = UIImageView(image: UIImage(named: "tableview_pull_refresh"))
    //风火轮
    private lazy var indicatorView: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
    //文本
    private lazy var messageLabel:UILabel = {
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: 14)
        label.textColor = UIColor.darkGray
        label.textAlignment = .center
        label.text = "下拉刷新"
        return label
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupUI() {
        addSubview(iconImageView)
        addSubview(messageLabel)
        addSubview(indicatorView)
        //手写布局
        iconImageView.translatesAutoresizingMaskIntoConstraints = false
        messageLabel.translatesAutoresizingMaskIntoConstraints = false
        indicatorView.translatesAutoresizingMaskIntoConstraints = false
        addConstraint(NSLayoutConstraint(item: iconImageView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: -35))
        
        addConstraint(NSLayoutConstraint(item: iconImageView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .leading, relatedBy: .equal, toItem: iconImageView, attribute: .trailing, multiplier: 1, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .centerY, relatedBy: .equal, toItem: iconImageView, attribute: .centerY, multiplier: 1, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: indicatorView, attribute: .centerX, relatedBy: .equal, toItem: iconImageView, attribute: .centerX, multiplier: 1, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: indicatorView, attribute: .centerY, relatedBy: .equal, toItem: iconImageView, attribute: .centerY, multiplier: 1, constant: 0))
    }
    //获取父控件
    override func willMove(toSuperview newSuperview: UIView?) {
        guard let scrollView = newSuperview as? UIScrollView else {
            return
        }
        //此时父视图可以滚动
        self.frame.size = CGSize(width: scrollView.frame.size.width, height: HMRefreshControlHeight)
        self.frame.origin.y = -HMRefreshControlHeight
        //kvo的方式监听垂直方向的偏移量
        //监听多个值  ->   [.new, .old]
        scrollView.addObserver(self, forKeyPath: "contentOffset", options: .new, context: nil)
        //记录当前滚动视图
        currentScrollView = scrollView
    }
    //kvo监听方法,只有contentOffset属性发生改变,就会回调这个方法
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        let contentOffSetY = currentScrollView!.contentOffset.y
        //临界点
        let maxY = -(currentScrollView!.contentInset.top + HMRefreshControlHeight)
        //拖动状态下才判断刷新z状态
        if currentScrollView!.isDragging {
            if contentOffSetY < maxY && HMState == .normal{
                //拖动时:1.下拉刷新;2.松手刷新
                //松手刷新pulling
                HMState = .pulling
            } else if contentOffSetY >= maxY && HMState == .pulling{
                //下拉刷新normal
                HMState = .normal
            }
        } else {
            //没有拖动
            //要想进入正在刷新:1.松手;2.松手就刷新的状态
            if HMState == .pulling {
                HMState = .refreshing
            }
        }
        
    }
    //移除kvo
    deinit {
        currentScrollView?.removeObserver(self, forKeyPath: "contentOffset")
    }
    
}
